import sys
import optparse
from socket import gethostbyname
from socket import gethostbyaddr
from socket import socket
from socket import AF_INET
from socket import SOCK_STREAM
from socket import setdefaulttimeout
import traceback
import threading
from threading import Semaphore
import logging

logger = logging.Logger(__name__)

parser = optparse.OptionParser(
    "Usage %prog -H <target host> -P <target ports>")
parser.add_option("-H", type="string", dest="targetHost",
                  help="specify target host")
parser.add_option("-P", type="string", dest="targetPorts",
                  help="specify target ports, seperated by ','")

screen_lock = Semaphore(value=1)


def parse_args():
    return parser.parse_args()


def connScan(targetIP, targetPort):
    try:
        connSocket = socket(AF_INET, SOCK_STREAM)
        connSocket.connect((targetIP, int(targetPort)))
        connSocket.send(bytes("hello there!\r\n", encoding="utf-8"))
        temp = connSocket.recv(100)
        screen_lock.acquire()
        print("\t[+] %s:%s/tcp open" % (targetIP, targetPort))
        print("\t[+] %s:%s/banner recv:%s" % (targetIP, targetPort, temp))
    except Exception as e:
        # print("error: %s" % traceback.format_exc())
        screen_lock.acquire()
        if not e:
            logger.error("Error : %s" % traceback.format_exc())
        print("\t[-] %s:%s/tcp closed" % (targetIP, targetPort))
    finally:
        screen_lock.release()
        try:
            connSocket.close()
        except:
            pass


def get_host_info(host):
    return gethostbyname(host)


def thread_run(targetIp, targetPort):
    scan_thread = threading.Thread(
        target=connScan, args=(targetIp, targetPort))
    scan_thread.start()


if __name__ == "__main__":
    options, args = parse_args()
    if not options.targetHost or not options.targetPorts:
        print(parser.usage)
        exit(-1)
    targetHost = options.targetHost
    targetPorts = options.targetPorts
    targetPorts = targetPorts.split(",")
    setdefaulttimeout(1)
    targetIp = get_host_info(targetHost)
    for targetPort in targetPorts:
        thread_run(targetHost, targetPort)
